﻿using System;
using System.Xml.Serialization;

namespace Kotonoha.Objects {
    public class TimedVariable {
        private const double TicksDaily = 10.0 * 1000 * 1000 * 60 * 60 * 24;
        private double min = -1e6;
        private double max = 1e6;

        public TimedVariable() {
            Id = -1;
            InitialValue = 0;
            Rate = 1;
            SetDate = DateTime.Now;
        }

        public TimedVariable(double start)
            : this() {
            InitialValue = start;
        }

        public TimedVariable(double start, double rate) : this(start) {
            Rate = rate;
        }

        public TimedVariable(double start, double rate, double min, double max)
            : this(start, rate) {
            Max = max;
            Min = min;
        }

        [XmlIgnore]
        public long Id { get; set; }

        [XmlAttribute]
        public DateTime SetDate { get; set; }
        [XmlAttribute]
        public double InitialValue { get; set; }
        [XmlAttribute]
        public double Rate { get; set; }

        [XmlIgnore]
        public double Value {
            get {
                return GetValue(DateTime.Now);
            }
        }

        public virtual double GetValue(DateTime forDate) {
            long diff = forDate.Ticks - SetDate.Ticks;
            double daysDiff = diff / TicksDaily;
            double val = InitialValue + Rate * daysDiff;
            return Math.Max(min, Math.Min(max, val));
        }

        public void Bounds(double minV, double maxV) {
            Min = minV;
            Max = maxV;
        }

        public void Add(double val) {
            Add(val, DateTime.Now);
        }

        public void Add(double val, DateTime when) {
            InitialValue = GetValue(when);
            SetDate = when;
            InitialValue += val;
        }

        [XmlAttribute]
        public double Min {
            get { return min; }
            set { min = value; }
        }

        [XmlAttribute]
        public double Max {
            get { return max; }
            set { max = value; }
        }

        public override string ToString() {
            return string.Format("{0:o}`{1}`{2}`{3}`{4}", SetDate, InitialValue, Rate, Min, Max);
        }

        public static TimedVariable parseFrom(string s) {
            string[] parts = s.Split('`');
            TimedVariable val = new TimedVariable();
            val.SetDate = DateTime.Parse(parts[0]);
            val.InitialValue = Double.Parse(parts[1]);
            val.Rate = double.Parse(parts[2]);
            val.min = double.Parse(parts[3]);
            val.max = double.Parse(parts[4]);
            return val;
        }
    }
}